package com.aracky.common.util;

import com.aracky.common.constants.LoginConstants;
import com.aracky.common.vo.LoginUserVO;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * @Author zengzhiping
 * @BelongsPackage com.aracky.system.filter
 * @CreateTime 2022-07-15
 * @Description
 */
@Component
@ConfigurationProperties(prefix = "jwt")
public class JWTUtil {
    //定义token返回头部
    public static String header;
    //token前缀
    public static String tokenPrefix;
    //签名密钥
    public static String secret;
    //有效期
    public static long expireTime;

    public void setHeader(String header) {
        JWTUtil.header = header;
    }

    public void setTokenPrefix(String tokenPrefix) {
        JWTUtil.tokenPrefix = tokenPrefix;
    }

    public void setSecret(String secret) {
        JWTUtil.secret = secret;
    }

    public void setExpireTime(int expireTimeInt) {
        JWTUtil.expireTime = expireTimeInt * 1000L * 60;
    }

    /**
     * 使用用户名和角色列表生成的一个token。具体可以更改
     *
     * @param jwtUser
     * @return
     */
    public static String createToken(LoginUserVO jwtUser, String jti) {
        Date now = new Date();
        return JWT.create()
                .withJWTId(jti)
                .withSubject(jwtUser.getLoginName())
                .withClaim(LoginConstants.USER.USER_ID, jwtUser.getUserId())
                .withClaim(LoginConstants.USER.REAL_NAME, jwtUser.getUsername())
                .withClaim(LoginConstants.USER.ROLE_KEY, jwtUser.getRoleList())
                .withIssuedAt(now)
                .withExpiresAt(new Date(System.currentTimeMillis() + expireTime))
                .sign(Algorithm.HMAC512(secret));
    }

    /**
     * 从HttpServletRequest中解析token
     *
     * @param bearerToken
     * @return
     */
    public static String resolveToken(String bearerToken) {
        if (bearerToken != null && bearerToken.startsWith(tokenPrefix)) {
            return bearerToken.substring(7).trim();
        }
        return null;
    }

    /**
     * 从token中解析jti
     *
     * @param token
     * @return java.lang.String
     * @date 2022/04/23 11:52
     */
    public static String getTokenId(String token) {
        DecodedJWT decodedJWT = JWT.decode(token);
        return decodedJWT.getId();
    }

    /**
     * 从token中解密数据后直接返回对象
     *
     * @param token
     * @return
     */
    public static LoginUserVO getUserInfo(String token) {
        //1.验证token是否正确
        DecodedJWT decodedJWT = validateTokenRight(token);

        //解析数据信息
        String loginName = decodedJWT.getSubject();
        Long userId = decodedJWT.getClaim(LoginConstants.USER.USER_ID).asLong();
        String realName = decodedJWT.getClaim(LoginConstants.USER.REAL_NAME).asString();
        List<String> roleKeyList = decodedJWT.getClaim(LoginConstants.USER.ROLE_KEY).asList(String.class);
        LoginUserVO loginUserVO = new LoginUserVO();
        loginUserVO.setLoginName(loginName);
        loginUserVO.setUserId(userId);
        loginUserVO.setUserName(realName);
        loginUserVO.setRoleList(roleKeyList);
        return loginUserVO;
    }

    /**
     * 检查token是否正确
     *
     * @param token
     * @return
     */
    private static DecodedJWT validateTokenRight(String token) {
        DecodedJWT verify = JWT.require(Algorithm.HMAC512(secret))
                .build()
                .verify(token);
        if (verify == null) {
            //证明密钥是错误的，让其重新登录
            throw new RuntimeException();
        }
        DecodedJWT decodedJWT = JWT.decode(token);

        if (decodedJWT.getExpiresAt().before(new Date())) {
            //token超时失效了，让其重新登录
            throw new RuntimeException();
        }
        return decodedJWT;
    }


}
